//
//  SingleCalendarView.swift
//  YOKO
//
//  Created by Lan on 16/4/19.
//  Copyright © 2016年 15Tec. All rights reserved.
//

import UIKit
import SnapKit

enum SingleCalendarViewStyle {
    case Add
    case Main
    case Deadline
    case Custom
}

enum SingleCalendarViewSelectedState: Int {
    case Normal
    case Focused
    case ShowDeleteButton
}

protocol SingleCalendarViewDelegate: class {
    func singleCalendarViewDidTap(singleCalendarView: SingleCalendarView)
    func singleCalendarViewDidLongPress(singleCalendarView: SingleCalendarView)
    func singleCalendarViewDidPressDeleteButton(singleCalendarView: SingleCalendarView)
}

class SingleCalendarView: UIView {
    
    private var __calendarNameLabel: UILabel!
    private var __calendarBackgroundView: UIImageView!
    private var __style: SingleCalendarViewStyle
    private var __calendarNameAbbreviationLabel: UILabel!
    private var __deleteButton: UIButton!
    private var __selectedState: SingleCalendarViewSelectedState
    private var __title: String?
    
    override var frame: CGRect {
        willSet {
            guard (newValue.size != frame.size) else { return }
            
            let ratio = min(newValue.width, newValue.height) / 69.0
            if __calendarNameLabel != nil {
                __calendarNameLabel.font = UIFont.systemFontOfSize(9.0 * ratio)
            }
            if __calendarNameAbbreviationLabel != nil {
                __calendarNameAbbreviationLabel.font = UIFont.boldSystemFontOfSize(19.0 * ratio)
            }
        }
    }
    
    var userInfo: AnyObject? //userInfo是weak属性表示不拥有该属性
    
    var delegate: SingleCalendarViewDelegate?
    
    var selectedState: SingleCalendarViewSelectedState {
        get { return __selectedState }
        set {
            if (__selectedState.rawValue == newValue.rawValue) {return} //避免不必要的更新
            
            __selectedState = newValue
            switch __selectedState {
            case .Normal:
                if (__deleteButton.hidden == false) {
                    UIView.animateWithDuration(0.4, delay: 0.0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.4, options: .CurveEaseInOut, animations:
                        {
                            self.__deleteButton.transform = CGAffineTransformMakeScale(0.0, 0.0)
                        }, completion:
                        { (complete) in
                            self.__deleteButton.hidden = true
                    })
                }
                self.layer.shadowOffset = CGSizeMake(0.0, 2.0)
                self.layer.shadowColor = UIColor.blackColor().CGColor
                self.layer.shadowOpacity = 0.8
                self.layer.shadowRadius = 4.0
            case .Focused:
                if (__deleteButton.hidden == false) {
                    UIView.animateWithDuration(0.4, delay: 0.0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.4, options: .CurveEaseInOut, animations:
                        {
                            self.__deleteButton.transform = CGAffineTransformMakeScale(0.0, 0.0)
                        }, completion:
                        { (complete) in
                            self.__deleteButton.hidden = true
                    })
                }
                self.layer.shadowOffset = CGSizeZero
                self.layer.shadowColor = UIColor.whiteColor().CGColor
                self.layer.shadowOpacity = 0.8
                self.layer.shadowRadius = 7.0
            case .ShowDeleteButton:
                self.__deleteButton.transform = CGAffineTransformMakeScale(0.0, 0.0)
                __deleteButton.hidden = false
                
                UIView.animateWithDuration(0.4, delay: 0.0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.4, options: .CurveEaseInOut, animations:
                    {
                        self.__deleteButton.transform = CGAffineTransformMakeScale(1.0, 1.0)
                    }, completion: nil)
                self.layer.shadowOffset = CGSizeZero
                self.layer.shadowColor = UIColor.whiteColor().CGColor
                self.layer.shadowOpacity = 0.8
                self.layer.shadowRadius = 7.0
            }
        }
    }
    
    var title: String? {
        get { return __title }
        set {
            //修改标题名字
            __title = (newValue == nil || newValue! == "") ? "未命名日历" : newValue!

            __calendarNameLabel.text = __title!.characters.count > 8 ? __title!.substringToIndex(__title!.startIndex.advancedBy(8)) : __title
            __calendarNameLabel.sizeToFit()

            if __style == .Custom {
                __calendarNameAbbreviationLabel.text = __title!.substringToIndex(__title!.startIndex.advancedBy(1))
                __calendarNameAbbreviationLabel.sizeToFit()
            }
        }
    }
    
    var style: SingleCalendarViewStyle {
        return __style
    }
    
    override init(frame: CGRect) {
        fatalError("SingleCalendarView: Cannot init with init(frame: CGRect)")
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("SingleCalendarView: Cannot init with init?(coder aDecoder: NSCoder)")
    }
    
    init(width: CGFloat, style: SingleCalendarViewStyle, userInfo: AnyObject?, withTitle title: String?) {
        
        __style = style
        __selectedState = .Normal
        self.userInfo = userInfo
        
        let ratio = width / 69.0
        
        super.init(frame: CGRectMake(0.0, 0.0, width, width))
        //self.backgroundColor = UIColor.blueColor()
        
        //初始化Delete Button
        __deleteButton = UIButton(type: .Custom)
        //__deleteButton.backgroundColor = UIColor.yellowColor()
        __deleteButton.setImage(UIImage(named: "delete"), forState: .Normal)
        __deleteButton.hidden = true
        __deleteButton.contentMode = .ScaleAspectFill
        self.addSubview(__deleteButton)
        __deleteButton.snp_makeConstraints {
            make in
            make.height.equalTo(15.0 * ratio)
            make.width.equalTo(15.0 * ratio)
            make.right.equalTo(self)
            make.top.equalTo(self)
        }
        
        //初始化Background View
        __calendarBackgroundView = UIImageView(image: nil)
        //__calendarBackgroundView.backgroundColor = UIColor.redColor()
        switch __style {
        case .Add:
            __calendarBackgroundView.image = UIImage(named: "old_add_calendar")
        case .Deadline:
            __calendarBackgroundView.image = UIImage(named: "old_deadline_calendar")
        case .Main:
            __calendarBackgroundView.image = UIImage(named: "old_main_calendar")
        default:
            __calendarBackgroundView.image = UIImage(named: "old_orange_calendar")
        }
        self.insertSubview(__calendarBackgroundView, belowSubview: __deleteButton)
        __calendarBackgroundView.snp_makeConstraints {
            make in
            make.left.equalTo(self)
            make.right.equalTo(self).offset(-7.5 * ratio)
            make.top.equalTo(self).offset(7.5 * ratio)
            make.bottom.equalTo(self)
        }
        
        //初始化Title View
        __calendarNameLabel = UILabel()
        //__calendarNameLabel.backgroundColor = UIColor.cyanColor()
        __calendarNameLabel.font = UIFont.systemFontOfSize(9.0 * ratio)
        __calendarNameLabel.textAlignment = .Center
        __calendarNameLabel.textColor = UIColor.whiteColor()
        __calendarBackgroundView.addSubview(__calendarNameLabel)
        __calendarNameLabel.snp_makeConstraints {
            make in
            make.centerX.equalTo(__calendarBackgroundView)
            make.centerY.equalTo(__calendarBackgroundView).multipliedBy(28.0 / 124.0)
        }
        
        //初始化中间的字
        if __style == .Custom {
            //如果是Custom才显示字
            __calendarNameAbbreviationLabel = UILabel()
            __calendarNameAbbreviationLabel.textAlignment = .Center
            __calendarNameAbbreviationLabel.font = UIFont.boldSystemFontOfSize(19.0 * ratio)
            __calendarNameAbbreviationLabel.textColor = UIColor.whiteColor()
            //__calendarNameAbbreviationLabel.backgroundColor = UIColor.brownColor()
            __calendarBackgroundView.addSubview(__calendarNameAbbreviationLabel)
            __calendarNameAbbreviationLabel.snp_makeConstraints {
                make in
                make.centerX.equalTo(__calendarBackgroundView)
                make.centerY.equalTo(__calendarBackgroundView).multipliedBy(76.0 / 62.0)
            }
        }
        
        switch __style {
        case .Add:
            self.title = "新建"
        case .Deadline:
            self.title = "Deadline"
        case .Main:
            self.title = "主日历本"
        case .Custom:
            self.title = title
        }
        
        //设置阴影
        self.layer.shadowOffset = CGSizeMake(0.0, 2.0)
        self.layer.shadowColor = UIColor.blackColor().CGColor
        self.layer.shadowOpacity = 0.8
        self.layer.shadowRadius = 4.0
        
        //添加手势控制
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(SingleCalendarView.tapHandler))
        let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(SingleCalendarView.longPressHandler))
        longPressGesture.minimumPressDuration = 1.0
        self.addGestureRecognizer(tapGesture)
        self.addGestureRecognizer(longPressGesture)
        __deleteButton.addTarget(self, action: #selector(SingleCalendarView.deleteHandler), forControlEvents: .TouchUpInside)
    }
    
    //MARK: - Handler
    @objc func tapHandler() {
        delegate?.singleCalendarViewDidTap(self)
    }
    
    @objc func longPressHandler() {
        
        //如果是.Main和.Add那么返回，因为不可以删除主日历本和新建日历本
        switch __style {
        case .Main, .Add:
            return
        default:
            break
        }
        
        guard __selectedState != .ShowDeleteButton else { return } //如果当前已经处于该状态那么不做任何事情
        
        selectedState = .ShowDeleteButton
        delegate?.singleCalendarViewDidLongPress(self)
    }
    
    @objc func deleteHandler() {
        delegate?.singleCalendarViewDidPressDeleteButton(self)
    }
}

protocol CalendarSelectorViewDelegate: class {
    func calendarSelectorViewDidTap(view: CalendarSelectorView, inView: SingleCalendarView, withUserInfo userInfo: AnyObject?) //在某个日历上按上了点击的事件
    func calendarSelectorViewDidPressDeleteButton(view: CalendarSelectorView, inView: SingleCalendarView, withUserInfo userInfo: AnyObject?) //在某个日历上按下了取消按键
    func calendarSelectorViewDidLongPress(view: CalendarSelectorView, inView: SingleCalendarView, withUserInfo userInfo: AnyObject?) //在某个日历上长按了
    func calendarSelectorViewDidPressNewCalendarView(view: CalendarSelectorView, inView: SingleCalendarView) //点击了新建的按钮
    func calendarSelectorViewDidPressTapBackgroundView(view: CalendarSelectorView) //用户点击了背景，可以在此处加上取消的设置
}

/// 包含了UIScrollView的日历选择的View
class CalendarSelectorView: UIView, SingleCalendarViewDelegate, UIScrollViewDelegate {
    
    //MARK: - 内部属性
    private var __scrollView: UIScrollView!
    private var __pageWidth: CGFloat = 0.0
    private var __pageHeight: CGFloat = 0.0
    private var __singleCalendarViews: [SingleCalendarView] {
        return __scrollView.subviews.filter {$0 is SingleCalendarView} as! [SingleCalendarView]
    }
    private var __pageControl: UIPageControl!
    private var __singleCalendarViewWidth: CGFloat = 69.0
    
    private var __hasLayoutSubview = false //这个用来判断UIView是否已经执行了一次layoutSubviews()，没有执行layoutSubviews的时候，scrollView无法正确布局
    
    //MARK: - 接口
    var singleCalendarsViews: [SingleCalendarView] { return __singleCalendarViews }
    var normalStateSingleCalendarsView: [SingleCalendarView] { return __singleCalendarViews.filter{$0.selectedState == .Normal}}
    var focusedStateSingleCalendarsView: [SingleCalendarView] {return __singleCalendarViews.filter{$0.selectedState == .Focused }}
    var deletedStateSingleCalendarsView: [SingleCalendarView] {return __singleCalendarViews.filter{$0.selectedState == .ShowDeleteButton}}
    
    var delegate: CalendarSelectorViewDelegate?
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        //在这里初始化UI是因为在layoutSubviews之前，scrollView的大小不确定
        //而在这里可以显示的调用scrollView.frame.width
        if __hasLayoutSubview == false {
            __hasLayoutSubview = true
            __pageWidth = __scrollView.frame.width
            __pageHeight = __scrollView.frame.height
            __singleCalendarViewWidth = __pageWidth / 4.0 * 0.75
            
            //初始化__scrollView和__pageControl
            __updateScrollViewContentSizeAndPageControl()
            __scrollView.setContentOffset(CGPointZero, animated: false)
            __pageControl.currentPage = 0
            
            //因为重新调整了pageWidth，所以更新所有加入的SingleCalendarSubview
            for singleCalendarView in __singleCalendarViews {
                singleCalendarView.frame.size = CGSizeMake(__singleCalendarViewWidth, __singleCalendarViewWidth)
                __updateLocationForView(singleCalendarView, withAnimation: false)
            }
        }
    }
    
    //MARK: - Init函数
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        __configureUI()
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        __configureUI()
    }
    
    init() {
        super.init(frame: CGRectZero)
        __configureUI()
    }
    
    //MARK: - 外部接口函数
    func addCalendar(withStyle style: SingleCalendarViewStyle, withUserInfo userInfo: AnyObject?, withName name: String?, animated: Bool) {
        
        //添加一个calendar，如果说type不等于.Custom的话，那么name会被忽略掉
        //userInfo为额外属性，调用delegate的时候会拿出来
        
        guard style != .Add else { return } //不可以添加新建时间的SingleCalendarView否则直接退出
        
        let newSingleCalendarView = SingleCalendarView(width: __singleCalendarViewWidth, style: style, userInfo: userInfo, withTitle: name)
        newSingleCalendarView.delegate = self
        
        __scrollView.insertSubview(newSingleCalendarView, belowSubview: __singleCalendarViews.last!) //添加在新建事件的前面
        
        if (__singleCalendarViews.count % 8 == 1) {
            //如果说两者不相等,新增scrollView和pageControl的长度
            __updateScrollViewContentSizeAndPageControl()
        }
        
        if __hasLayoutSubview == false {
            //如果还没有初始化scrollView的大小
            //不更新UI
            return
        }
        
        //更新新建Calendar的位置
        __updateLocationForView(__singleCalendarViews.last!, withAnimation: animated)
        __updateLocationForView(newSingleCalendarView, withAnimation: false)
        
        if animated {
            newSingleCalendarView.transform = CGAffineTransformMakeScale(0.0, 0.0)
            UIView.animateWithDuration(0.4, delay: 0.0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.4, options: .CurveEaseInOut, animations:
                {
                    () -> Void in
                    newSingleCalendarView.transform = CGAffineTransformIdentity
                }, completion: nil)
        }
    }
    
    func deleteCalendar(atIndex index: Int, animated: Bool) {
        //根据index删除具体的calendar
        deleteCalendar(__singleCalendarViews[index], animated: animated)
    }
    
    func deleteCalendar(view: SingleCalendarView, animated: Bool) {
        let index = __singleCalendarViews.indexOf(view)!
        let shouldResizeContentSize = (__singleCalendarViews.count % 8 == 1)
        
        UIView.setAnimationsEnabled(animated)
        UIView.animateWithDuration(0.3, animations:
        {
            view.transform = CGAffineTransformMakeScale(0.01, 0.01)
        }) { (complete) in
            view.removeFromSuperview()
            for var i in index..<self.__singleCalendarViews.count {
                self.__updateLocationForView(self.__singleCalendarViews[i], withAnimation: animated)
            }
            if shouldResizeContentSize == true {
                self.__updateScrollViewContentSizeAndPageControl()
                if self.__scrollView.contentOffset.x > self.__scrollView.contentSize.width - self.__pageWidth {
                    self.__scrollView.setContentOffset(CGPointMake(self.__scrollView.contentSize.width - self.__pageWidth, 0.0), animated: true)
                }
            }
        }
        UIView.setAnimationsEnabled(true)
    }
    
    func changeCalendarName(atIndex index: Int, toName name: String) {
        (__singleCalendarViews[index]).title = name
    }
    
    func changeCalendarName(forView view: SingleCalendarView, toName name: String) {
        view.title = name
    }
    
    func setState(atIndex index: Int, forState state: SingleCalendarViewSelectedState) {
        __singleCalendarViews[index].selectedState = state
    }
    
    func setState(forView view: SingleCalendarView, forState state: SingleCalendarViewSelectedState) {
        view.selectedState = state
    }
    
    //MARK: - 一些辅助函数
    
    private func __indexForView(view: SingleCalendarView) -> Int? {
        /**
         返回一个SingleCalendarView在该CalendarSelectorView中呈现的位置，
         如果在该CalendarSelectorView中没有出现过，那么返回nil
         在下面没有用
         */
        for (i, scanView) in singleCalendarsViews.enumerate() {
            if (scanView == view) { return i}
        }
        return nil
    }
    
    private func __configureUI() {
        //添加阴影
        self.layer.shadowRadius = 4.0
        self.layer.shadowColor = UIColor.blackColor().CGColor
        self.layer.shadowOffset = CGSizeMake(0.0, 2.0)
        self.layer.shadowOpacity = 0.5
        
        //初始化scrollView
        __scrollView = UIScrollView()
        self.addSubview(__scrollView)
        __scrollView.snp_makeConstraints {
            make in
            make.edges.equalTo(self)
        }
        __scrollView.backgroundColor = YOKOColor.TypeColors[0]
        __scrollView.delegate = self
        __scrollView.alwaysBounceVertical = false
        __scrollView.alwaysBounceHorizontal = false
        
        //初始化一个新建的SingleCalendarView
        let addSingleCalendarView = SingleCalendarView(width: __singleCalendarViewWidth, style: .Add, userInfo: nil, withTitle: "")
        addSingleCalendarView.delegate = self
        __scrollView.addSubview(addSingleCalendarView)
        
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(CalendarSelectorView.tapGestureHandler))
        self.addGestureRecognizer(tapGestureRecognizer)
        
        __scrollView.pagingEnabled = true
        
        //初始化__pageControl
        __pageControl = UIPageControl()
        self.addSubview(__pageControl)
        __pageControl.snp_makeConstraints {
            make in
            make.centerX.equalTo(self)
            make.bottom.equalTo(self)
        }
    }
    
    private func __groupIndexForIndex(index: Int) -> (groupIndex: Int, rowIndex: Int, columnIndex: Int) {
        //根据给定的index返回所在的组，行和列
        let groupIndex = index / 8
        let numIndexInGroup = index % 8
        let rowIndex = numIndexInGroup / 4
        let columnIndex = numIndexInGroup % 4
        return (groupIndex, rowIndex, columnIndex)
    }
    
    private func __groupIndexForView(view: SingleCalendarView) -> (groupIndex: Int, rowIndex: Int, columnIndex: Int) {
        //根据给定的view返回group index
        //view必须在__singleCalendarsViews当中
        let index = __singleCalendarViews.indexOf(view)!
        return __groupIndexForIndex(index)
    }
    
    private func __locationForIndex(index: Int) -> (centerX: CGFloat, centerY: CGFloat) {
        //根据给定的index返回需要放置的位置
        //如果应该放在上排，那么bottomSpace返回nil
        //如果应该放在下排，那么topSpacing返回nil
        var centerX: CGFloat
        var centerY: CGFloat
        
        let (group, row, column) = __groupIndexForIndex(index)
        if (row == 0) {
            centerY = __pageHeight * 0.25
        }
        else {
            centerY = __pageHeight * 0.65
        }
        
        centerX = __pageWidth * (CGFloat(column) + 0.5) / 4.0 + __pageWidth * CGFloat(group) + 3.75 //最后的3.75是修正系数，修正了原来的中心点因为多加了一个delete按钮造成的偏移
        return (centerX, centerY)
    }
    
    private func __locationForView(view: SingleCalendarView) -> (centerX: CGFloat, centerY: CGFloat) {
        return __locationForIndex(__singleCalendarViews.indexOf(view)!)
    }
    
    private func __updateLocationForView(view: SingleCalendarView, withAnimation animated: Bool) {
        
        let (centerX, centerY) = __locationForView(view)
        if animated == false {
            view.center = CGPointMake(centerX, centerY)
            return
        }
        
        //else
        UIView.animateWithDuration(0.4, delay: 0.0, options: .CurveEaseInOut, animations:
            {
                () -> Void in
                view.center = CGPointMake(centerX, centerY)
            }, completion: nil)
    }
    
    private func __updateScrollViewContentSizeAndPageControl() {
        var numberOfPage = (__singleCalendarViews.count - 1) / 8  + 1
        if (numberOfPage <= 0) {numberOfPage = 1} //0个calendar也需要有1页
        
        __pageControl.numberOfPages = numberOfPage
        __scrollView.contentSize = CGSizeMake(CGFloat(numberOfPage) * __pageWidth, __pageHeight)
    }
    
    //MARK: - SingleCalendarViewDelgate处理
    func singleCalendarViewDidTap(singleCalendarView: SingleCalendarView) {
        if (singleCalendarView.__style == .Add) {
            //如果点击的是新建的Calendar的话
            delegate?.calendarSelectorViewDidPressNewCalendarView(self, inView: singleCalendarView)
        }
        else {
            delegate?.calendarSelectorViewDidTap(self, inView: singleCalendarView, withUserInfo: singleCalendarView.userInfo)
        }
    }
    
    func singleCalendarViewDidPressDeleteButton(singleCalendarView: SingleCalendarView) {
        delegate?.calendarSelectorViewDidPressDeleteButton(self, inView: singleCalendarView, withUserInfo: singleCalendarView.userInfo)
    }
    
    func singleCalendarViewDidLongPress(singleCalendarView: SingleCalendarView) {
        delegate?.calendarSelectorViewDidLongPress(self, inView: singleCalendarView, withUserInfo: singleCalendarView.userInfo)
    }
    
    //MARK: - UIScrollViewDelegate处理函数
    @objc func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
        
        //下面防止出现不处于page的位置，一般当用户用力撞击边界的时候会产生
        let contentOffsetToPageIndex = Int(round(__scrollView.contentOffset.x / __pageWidth))
        let nearestContentOffset = CGFloat(contentOffsetToPageIndex) * __pageWidth
        if (__scrollView.contentOffset.x != nearestContentOffset) {
            __scrollView.setContentOffset(CGPointMake(nearestContentOffset, 0.0), animated: true)
        }
        
        //更新__pageControl的位置
        __pageControl.currentPage = contentOffsetToPageIndex
    }
    
    //MARK: - Handler
    func tapGestureHandler() {
        delegate?.calendarSelectorViewDidPressTapBackgroundView(self)
    }
}

protocol CalendarViewDelegate: class {
    func calendarViewDidAddNewCalendar(calendarView: CalendarView, forName name: String)
    func calendarViewDidTapCalendar(calendarView: CalendarView, atIndex index: Int, withUserInfo userInfo: AnyObject?)
    func calendarViewDidPressCalendarDeleteButton(calendarView: CalendarView, atIndex index: Int, withUserInfo userInfo: AnyObject?, isCurrentSelectedView: Bool)
    func calendarViewDidChangeNameForCalendar(calendarView: CalendarView, toName name: String, atIndex index: Int, withUserInfo userInfo: AnyObject?)
}

protocol CalendarViewDataSource: class {
    func calendarView_numberOfCalendars() -> Int
    func calendarView_nameForCalendarAtIndex(index: Int) -> String
    func calendarView_userInfoForCalendarAtIndex(index: Int) -> AnyObject?
    func calendarView_indexForSelectedCalendar() -> Int
}

//CalendarSelectorView的Controller组件，用来同步信息等
class CalendarView: UIView, CalendarSelectorViewDelegate {
    
    //MARK: - @IBOutlet
    @IBOutlet weak var calendarSelectorView: CalendarSelectorView!
    @IBOutlet weak var editView: UIView!
    @IBOutlet weak var editTextField: UITextField!
    @IBOutlet weak var editCommitButton: UIButton!
    @IBOutlet weak var editViewTopConstraint: NSLayoutConstraint! //用来做动画的
    @IBOutlet weak var editTextFieldAndButtonContainerView: UIView!
    
    //MARK: - 控制变量
    private var __currentSelectedView: SingleCalendarView? //当前正在高亮显示的SingleCalendarView
    
    //MARK: - delegate
    var delegate: CalendarViewDelegate?
    var datasource: CalendarViewDataSource?
    
    override func awakeFromNib() {
        super.awakeFromNib()
        
        calendarSelectorView.delegate = self
        editCommitButton.addTarget(self, action: #selector(CalendarView.__editCommitButtonHandler), forControlEvents: .TouchUpInside)
        editTextFieldAndButtonContainerView.layer.cornerRadius = 4.0
        
    }
    
    //MARK: - editView弹出弹入动画
    @objc private func __editViewMoveUp() {
        /**
         *  收起editView区域，确保在layoutSubviews()之后调用，这样editView.frame.height可以使用
         */
        if self.editView.hidden == true {
            return
        }
        self.editTextField.resignFirstResponder()

        UIView.animateWithDuration(0.5, delay: 0.0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.4, options: .CurveEaseIn, animations:
            {
                () -> Void in
                self.editViewTopConstraint.constant = -self.editView.frame.height
                self.layoutIfNeeded()
            }) { (complete) in
                self.editView.hidden = true
        }
    }
    
    @objc private func __editViewMoveDown(withTextFieldBecomeFirstResponder withTextFieldBecomeFirstResponder: Bool) {
        /**
         *  展示editView区域，确保在layoutSubviews()调用
         */
        if editView.hidden == false {
            return
        }
        editView.hidden = false
        UIView.animateWithDuration(0.5, delay: 0.0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.4, options: .CurveEaseIn, animations:
            {
                () -> Void in
                self.editViewTopConstraint.constant = -3.0
                self.layoutIfNeeded()
        }) {
            (complete) in
            if withTextFieldBecomeFirstResponder == true {
                self.editTextField.becomeFirstResponder()
            }
        }
    }
    
    //MARK: - calendarSelectorViewDelegate函数
    func calendarSelectorViewDidPressNewCalendarView(view: CalendarSelectorView, inView: SingleCalendarView) {
        /**
         当点击了新建Calendar按钮后的处理函数
         
         - parameter view: 所点击的CalendarSelectorView
         - parameter inView: 所点击的SingleCalendarView
         */
        
        //暂时性的取消所有的高亮，除了最后一个
        for singleCalendarView in calendarSelectorView.singleCalendarsViews {
            if singleCalendarView.selectedState != .Normal && singleCalendarView != inView {
                singleCalendarView.selectedState = .Normal
            }
        }
        calendarSelectorView.setState(forView: inView, forState: .Focused)
        
        __editViewMoveDown(withTextFieldBecomeFirstResponder: true)
        editTextField.text = ""
        editTextField.placeholder = "请输出新日历的名称"
    }
    
    func calendarSelectorViewDidPressTapBackgroundView(view: CalendarSelectorView) {
        __editViewMoveUp()
        __restoreAllSingleCalendarViews()
    }
    
    func calendarSelectorViewDidTap(view: CalendarSelectorView, inView: SingleCalendarView, withUserInfo userInfo: AnyObject?) {
        //guard inView.selectedState == .Normal else { return } //如果当前已经被选择或者处于改名的状态那么忽略点击
        __editViewMoveUp()
        
        let viewIndex = view.__indexForView(inView)!
        delegate?.calendarViewDidTapCalendar(self, atIndex: viewIndex, withUserInfo: inView.userInfo)
    }
    
    func calendarSelectorViewDidLongPress(view: CalendarSelectorView, inView: SingleCalendarView, withUserInfo userInfo: AnyObject?) {
        /**
         * LongPress的处理函数
         */
        //如果当前已经存在了一个ShowDeletedButton，那么取消掉该ShowDeletedButton
        for showDeletedButtonView in calendarSelectorView.deletedStateSingleCalendarsView {
            if showDeletedButtonView != inView {
                __restoreSingleCalendarView(showDeletedButtonView)
            }
        }
        for singleCalendarView in calendarSelectorView.singleCalendarsViews.filter({$0.selectedState == .Focused}) {
            singleCalendarView.selectedState = .Normal //取消所有当前高亮的Calendar
        }
        
        //当前的view变成ShowDeletedButton的state
        inView.selectedState = .ShowDeleteButton
        
        //editView下拉
        __editViewMoveDown(withTextFieldBecomeFirstResponder: true)
        editTextField.text = inView.title
        editTextField.placeholder = nil
    }
    
    func calendarSelectorViewDidPressDeleteButton(view: CalendarSelectorView, inView: SingleCalendarView, withUserInfo userInfo: AnyObject?) {
        __editViewMoveUp()
        
        let viewIndex = view.__indexForView(inView)!
        delegate?.calendarViewDidPressCalendarDeleteButton(self, atIndex: viewIndex, withUserInfo: userInfo, isCurrentSelectedView: inView == __currentSelectedView)
    }
    
    //MARK: - Handler
    @objc private func __editCommitButtonHandler() {
        /**
         * editCommitButton的处理函数
         */
        
        if (editTextField.text == nil || editTextField.text == "") {
            //如果当前输入为空，那么待处理
            print("请输入日历本名称")
            return
        }
        
        if editTextField.placeholder != nil {
            //如果当前为新建日历本
            __editViewMoveUp()
            
            //重置所有的singleCalendarViews
            __restoreAllSingleCalendarViews()
            
            delegate?.calendarViewDidAddNewCalendar(self, forName: editTextField.text!)
        }
        else {
            //如果当前为改名
            let viewToChangeName = calendarSelectorView.deletedStateSingleCalendarsView.last!
            calendarSelectorView.changeCalendarName(forView: viewToChangeName, toName: editTextField.text!)
            
            let viewIndex = calendarSelectorView.__indexForView(viewToChangeName)!
            delegate?.calendarViewDidChangeNameForCalendar(self, toName: editTextField.text!, atIndex: viewIndex, withUserInfo: viewToChangeName.userInfo)
            
            __editViewMoveUp()
            __restoreAllSingleCalendarViews()
        }
    }
    
    //MARK: - 辅助函数
    
    private func __changeSelectedCalendar(toView view: SingleCalendarView) {
        __currentSelectedView = view
        __restoreAllSingleCalendarViews()
    }
    
    private func __restoreSingleCalendarView(view: SingleCalendarView) {
        if view != __currentSelectedView && view.selectedState != .Normal {
            calendarSelectorView.setState(forView: view, forState: .Normal)
        }
        else if view == __currentSelectedView {
            calendarSelectorView.setState(forView: view, forState: .Focused)
        }
    }
    
    private func __restoreAllSingleCalendarViews() {
        /**
         *  重置所有的singleCalendarsViews
         */
        for singleCalendarView in calendarSelectorView.singleCalendarsViews {
            __restoreSingleCalendarView(singleCalendarView)
        }
    }
    
    //MARK: - 接口程序
    func changeSelectedCalendar() {
        /**
         *  改变当前选择的日历
         */
        guard let datasource = self.datasource else {
            print("\(#function) --> No datasource")
            return
        }
        
        let index = datasource.calendarView_indexForSelectedCalendar()
        guard index >= 0 && index <= datasource.calendarView_numberOfCalendars() else {
            print("\(#function) --> Error to edit a invalid index calendar")
            return
        }
        
        let viewOfIndex = calendarSelectorView.singleCalendarsViews[index]
        __changeSelectedCalendar(toView: viewOfIndex)
    }
    
    func addCalendar(animated: Bool) {
        /**
         在最后添加Calendar，所有的信息从Datasource里面拿到
         */
        guard let datasource = self.datasource else {
            print("\(#function) --> No datasource")
            return
        }
        
        let index = datasource.calendarView_numberOfCalendars() - 1
        guard index >= 0 else {
            print("\(#function) --> Error to add a invalid index calendar")
            return
        }
        
        let name = datasource.calendarView_nameForCalendarAtIndex(index)
        let userInfo = datasource.calendarView_userInfoForCalendarAtIndex(index)
        
        if (name == "主日历" || name == "主日历本") {
            calendarSelectorView.addCalendar(withStyle: .Main, withUserInfo: userInfo, withName: name, animated: animated)
        }
        else if (name == "截止" || name == "截止日期" || name == "截止时间" || name.lowercaseString == "deadline") {
            calendarSelectorView.addCalendar(withStyle: .Deadline, withUserInfo: userInfo, withName: name, animated: animated)
        }
        else {
            calendarSelectorView.addCalendar(withStyle: .Custom, withUserInfo: userInfo, withName: name, animated: animated)
        }
    }
    
    func deleteCalendar(atIndex index: Int, animated: Bool) {
        guard let datasource = self.datasource else {
            print("\(#function) --> No datasource")
            return
        }
        guard index >= 0 && index <= datasource.calendarView_numberOfCalendars() else {
            print("\(#function) --> Error to edit a invalid index calendar")
            return
        }
        calendarSelectorView.deleteCalendar(atIndex: index, animated: animated)
    }
    
    func reloadCalendarName(atIndex index: Int) {
        guard let datasource = self.datasource else {
            print("\(#function) --> No datasource")
            return
        }
        guard index >= 0 && index <= datasource.calendarView_numberOfCalendars() else {
            print("\(#function) --> Error to edit a invalid index calendar")
            return
        }
        
        let name = datasource.calendarView_nameForCalendarAtIndex(index)
        calendarSelectorView.changeCalendarName(atIndex: index, toName: name)
    }
    
    func reloadCalendarUserInfo(atIndex index: Int) {
        guard let datasource = self.datasource else {
            print("\(#function) --> No datasource")
            return
        }
        guard index >= 0 && index <= datasource.calendarView_numberOfCalendars() else {
            print("\(#function) --> Error to edit a invalid index calendar")
            return
        }
        
        let userInfo = datasource.calendarView_userInfoForCalendarAtIndex(index)
        calendarSelectorView.singleCalendarsViews[index].userInfo = userInfo
    }
    
    func reloadAll() {
        /**
         *  重新载入所有的Calendar，比较耗费时间
         */
        guard let datasource = self.datasource else {
            print("\(#function) --> No datasource") 
            return
        }
        
        for calendar in calendarSelectorView.singleCalendarsViews {
            if calendar.style != .Add {
                calendar.removeFromSuperview()
            }
        }
        calendarSelectorView.__updateScrollViewContentSizeAndPageControl()
        
        //添加所有的CalendarView
        let calendarsCount = datasource.calendarView_numberOfCalendars()
        for i in 0..<calendarsCount {
            let name = datasource.calendarView_nameForCalendarAtIndex(i)
            let userInfo = datasource.calendarView_userInfoForCalendarAtIndex(i)
            if (name == "主日历" || name == "主日历本") {
                calendarSelectorView.addCalendar(withStyle: .Main, withUserInfo: userInfo, withName: name, animated: false)
            }
            else if (name == "截止" || name == "截止日期" || name == "截止时间" || name.lowercaseString == "deadline") {
                calendarSelectorView.addCalendar(withStyle: .Deadline, withUserInfo: userInfo, withName: name, animated: false)
            }
            else {
                calendarSelectorView.addCalendar(withStyle: .Custom, withUserInfo: userInfo, withName: name, animated: false)
            }
        }
        
        //重新设置当前的选择的Calendar
        changeSelectedCalendar()
        
        //将命名框等上拉
        __editViewMoveUp()
        __restoreAllSingleCalendarViews()
    }
}
